#ifndef HOUSINGDBMS_H
#define HOUSINGDBMS_H

#include <QObject>
#include <QString>
#include <QDir>
#include <QDebug>

#include "sleeqhash_bdb.h"
#include "lorismessenger.h"
#include "modelcontainerbase.h"


#include <QIODevice>

//DATA BASES
#define LAKDB_NUM      9

//#define LAKDB_FAMILIES_DICT    0
//#define LAKDB_NAMES_DICT       1
#define LAKDB_STREETS           0
#define LAKDB_HOUSES            1
#define LAKDB_APARTMENTS    2
#define LAKDB_TENANTS           3
#define LAKDB_LEASES             4
#define LAKDB_FAMILIES            5
#define LAKDB_DECMASTERS    6
#define LAKDB_PAYMENTS         7
#define LAKDB_BILLS         8



//STREET TYPES
#define ST_STRT   0
#define ST_LANE   1
#define ST_TERR   2
#define ST_PASS   3

//STREET FIELDS
#define FLD_STDB_NAME   0//string indx
#define FLD_STDB_TYPE   1 //int

//HOUSE FIELDS
#define FLD_HSDB_STINDEX    0  //quint64
#define FLD_HSDB_NAME       1  //string
#define FLD_HSDB_SPC        2  //double
#define FLD_HSDB_FACILITIES 3  //int (bits on/off)
#define FLD_HSDB_TARIFF     4  //double
#define FLD_HSDB_TYPE       5  //(apartments building / hostel) int indx
#define FLD_HSDB_COMMENTS   6  //just a comments QString

//APARTMENTS DB
#define FLD_APDB_HSINDEX    0 //house index     quint64                 indx
#define FLD_APDB_NUMBER     1 //in-house number int                     indx
#define FLD_APDB_TSPC       2 //total space     double                  indx
#define FLD_APDB_LSPSHASH  3 //live spaces      QVariantHash
#define FLD_APDB_RCOUNT     4 //room count      int
#define FLD_APDB_COMMENTS   5 //just a comments QString
#define FLD_APDB_PDATEHASH      6//dates of privatization  QVariantHash

//PERSONS FIELDS
#define FLD_PERS_FAMILY     0 // string   indx
#define FLD_PERS_NAME       1 // string
#define FLD_PERS_PNAME      2 // string
#define FLD_PERS_DOB        3 //QDate indx

//TENANTS DB FIELDS
#define FLD_TEN_FAM             0 //string index
#define FLD_TEN_NAME         1//string
#define FLD_TEN_PNAME       2//string
#define FLD_TEN_DOB            3//Date
#define FLD_TEN_PASSNUM     4// string(masked) passport ser/num
#define FLD_TEN_PASSDATE    5// QDate passport date
#define FLD_TEN_PASSDEP     6// String passport delivery department
#define FLD_TEN_REGADR      7// String registration adress
#define FLD_TEN_COMM        8// String comments

//LEASES DB FILEDS
#define FLD_LS_TINDEX       0// quint64 tenant index
#define FLD_LS_AINDEX       1// quint64 apartment index
#define FLD_LS_SPSLST     2// StringList leased space indices
#define FLD_LS_SDATE        3// date    index
#define FLD_LS_EDATE        4// date    index
#define FLD_LS_NUM          5// int indx
#define FLD_LS_COMM         6// string comments
#define FLD_LS_LENDER_HEAD  7//string
#define FLD_LS_LENDER_HFIO  8//string
#define FLD_LS_REASON       9 //string
#define FLD_LS_DECLST       10//List of qv_key
#define FLD_LS_DDATESLST    11//List decision dates list
#define FLD_LS_DNUMLST      12//list of string

//FAMILY DB FIELDS
#define FLD_FAM_TINDEX      0 //quint64 tenat index
#define FLD_FAM_FAM            1 //string index
#define FLD_FAM_NAME         2//string
#define FLD_FAM_PNAME       3//string
#define FLD_FAM_DOB            4//Date
#define FLD_FAM_RELATION    5 //string person relation

//DECISIONS MASTER DB
#define FLD_DECDB_NAME    0   //QString name

//LEASE DECISIONS DB
#define FLD_LDEC_LINDEX  0    //quint64 indx
#define FLD_LDEC_DINDEX  1   //quint64
#define FLD_LDEC_DATE     2   //Date

//PAYMENTS DB
#define FLD_PAY_BINDEX            0 //quint64 bill index            indexed
#define FLD_PAY_AINDEX           1 //quint64 apartment index  indexed
#define FLD_PAY_LINDEX            2 //lease index or zero         indexed
#define FLD_PAY_TARGETDATE  3//qdate                              indexed
#define FLD_PAY_AMMOUNT      4//double
#define FLD_PAY_SPSLST         5 //spaces ids StringList
#define FLD_PAY_DATE              6 //qdate                             indexed

//bills db
#define FLD_BILL_AINDEX         0//quint64 apartment index indexed;
#define FLD_BILL_TARGETDATE     1//target date indexed
#define FLD_BILL_SPSLST        2//spaces id  StringList
#define FLD_BILL_AMMOUNT        3// money
#define FLD_BILL_LINDEX         4//Lease index or 0. indexed
#define FLD_BILL_TARIFF         5//Tariff double

#define HDBMS_VERSION   "A.3"

#define RUSTR(s) QString::fromUtf8(s)

class ModelContainerBase;

struct HousingSettings
{
    QString str_home_path;
};


class HousingDBMS: public QObject
{
    Q_OBJECT
protected:
    QDir m_home_dir;
    bool m_state_ok;
    bool m_write_enabled;
    QStringList m_db_names;
    SleeQHash_BDB m_dbs[LAKDB_NUM];
    bool check_home_access();
    ModelContainerBase *mp_models;
    QString mqstr_db_vers;

public:
    static QString gen_hash_str_key();
    static LorisMessenger m_msngr, m_fmsngr, m_msngr_e;
    HousingDBMS(QObject *parent = 0);
    inline LorisMessenger *m() {return &m_msngr;}
    inline LorisMessenger *f() {return &m_fmsngr;}
    bool open_db(HousingSettings &hs);
    void set_models(ModelContainerBase *p_models);

    inline ModelContainerBase *get_models() {return mp_models;}

 //main data functions
    QVariant db_put(int db_index, const SLEE_HDB_REC &qh_data, const QVariant &qv_key = QVariant());

 //get data function
    SLEE_HDB_REC_LST get_db_data(int db_index, QVariantList &qv_pkeys_lst);
    SLEE_HDB_REC get_data(int db_index, const QVariant &qv_key);

    SleeQHash_BDB   * get_db(int db_index);
    int     get_apartment_htype(const QVariant &qv_ap_index);

    static QStringList get_street_types(bool do_full = false);
    static QString get_street_type(int i);
    static QString get_street_info(const SLEE_HDB_REC &qh_data,  bool do_reversed = false);
    QString get_street_info(const QVariant &qv_index,  bool do_reversed = false);


    SLEE_HDB_REC_LST get_leases_for(const QVariant &qv_ap_index, const QVariant &qv_date = QVariant());
    SLEE_HDB_REC_LST get_leases_at(const QVariant &qv_date);
    SLEE_HDB_REC_LST get_leases_in(const QVariant &qv_ap_index, const QVariant &qv_sdate, const QVariant &qv_edate);
    SLEE_HDB_REC_LST get_leases_at_month(const QVariant &qv_date);


    static QString get_tenant_fio(const SLEE_HDB_REC &qh_data, bool full_fio=false);
    QString  get_tenant_fio(const QVariant &qv_t_index, bool full_fio = false);
    static QString get_tenant_dob_str(const SLEE_HDB_REC &qh_data, bool do_wide_format = false);
    QString  get_tenant_dob_str(const QVariant &qv_t_index, bool do_wide_format = false);

    static QString get_fam_member_fio(const SLEE_HDB_REC & qh_data, bool full_fio = false);

    QString  get_house_addr(const SLEE_HDB_REC &qh_data);
    QString  get_house_addr(const QVariant &qv_h_index);
    static QString get_house_info(const SLEE_HDB_REC &qh_data);
    QString get_house_info(const QVariant &qv_h_key);
    int     get_house_type(const QVariant &qv_h_index);
    static QString get_house_type(int type);
    static QStringList get_house_types(bool do_full = false);

    QString get_apartment_addr(const QVariant &qv_ap_index);
    QString get_apartment_addr(const SLEE_HDB_REC &qh_data);
    QString get_apartment_info(const SLEE_HDB_REC &qh_data, bool add_address = true);
    QString get_apartment_info(const QVariant &qv_ap_index, bool add_address = true);
    double get_apartment_lspace(const QVariant &qv_a_index, const QStringList &qstrl_sp_ids = QStringList(), QStringList *p_qstrl_bad_ids = NULL);
    double get_apartment_lspace(const QVariantHash &qvh_lspaces, const QStringList &qstrl_sp_ids = QStringList(), QStringList *p_qstrl_bad_ids = NULL);

    QString  get_lease_info(const SLEE_HDB_REC &qh_data);
    QString  get_lease_info(const QVariant &qv_l_index);
    double get_leases_space(const QVariant &qv_ls_index);
    double get_leases_space(const SLEE_HDB_REC & qh_data);
    int get_leases_rooms_count(const SLEE_HDB_REC &qh_data);

    QVariantList get_lease_for_ap(const QVariant &qv_ap_index, const QDate &qd = QDate());

 //utilities functions
inline const QStringList &get_db_names() {return m_db_names;}
             QStringList  get_db_fld_names(int db_index);
        bool can_remove(int db_index, QVariant qv_key);

        void privatize_lspace(const QVariant &qv_a_index, const QStringList & qsl_spaces_ids, const QList<QDate> & qdl_pdates);

    static QStringList get_facilities_list(int facilities, bool do_compact = false);

    static QString get_person_fio_inf(const SLEE_HDB_REC &qh_data, bool full_fio = false, bool short_year = false);
    static QStringList get_fam_relations();
signals:
    void info_message(QString);
    void fast_message(QString);
    void error_message(QString);
};


inline static QDebug lakhMsg() {return QDebug(&HousingDBMS::m_msngr);}
inline static QDebug lakhMsgE() {return QDebug(&HousingDBMS::m_msngr_e);}
inline static QDebug lakhMsgF() {return QDebug(&HousingDBMS::m_fmsngr);}

#endif // HOUSINGDBMS_H
